package com.aiti.lulian.gxmh.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.service.iml.BaseSerivceImpl;
import com.aiti.base.core.exception.BusinessException;
import com.aiti.base.core.page.PageInfo;
import com.aiti.base.core.page.PageResult;
import com.aiti.lulian.constant.GxmhConstant;
import com.aiti.lulian.gxmh.dto.*;
import com.aiti.lulian.gxmh.entity.GxmhCustomizeForm;
import com.aiti.lulian.gxmh.entity.GxmhCustomizeFormMeta;
import com.aiti.lulian.gxmh.entity.GxmhCustomizeFormType;
import com.aiti.lulian.gxmh.entity.GxmhPolicyDeclare;
import com.aiti.lulian.gxmh.service.GxmhCustomizeFormMetaService;
import com.aiti.lulian.gxmh.service.GxmhCustomizeFormService;
import com.aiti.lulian.gxmh.service.GxmhPolicyDeclareService;
import com.aiti.lulian.gxmh.vo.GxmhCustomizeFormVo;
import com.aiti.lulian.mapper.gxmh.*;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * description:
 * auth fcb
 * date 2025-07-05 16:34
 **/
@Service
@Slf4j
public class GxmhCustomizeFormServiceImpl extends BaseSerivceImpl<GxmhCustomizeFormMapper, GxmhCustomizeForm> implements GxmhCustomizeFormService {

    @Autowired
    private GxmhSysMapper gxmhSysMapper;
    @Autowired
    private GxmhCustomizeFormMetaMapper gxmhCustomizeFormMetaMapper;
    @Autowired
    private GxmhCustomizeFormMetaService gxmhCustomizeFormMetaService;
    @Autowired
    private GxmhPolicyDeclareService gxmhPolicyDeclareService;
    @Autowired
    private GxmhCustomizeFormTypeMapper gxmhCustomizeFormTypeMapper;

    /**
     * 查询自定义表单列表
     * @param queryDto
     * @param loginId
     * @return
     */
    @Override
    public PageResult<GxmhCustomizeFormVo> getFormPageList(GxmhCustomizeFormQueryDto queryDto, String loginId) {
        IPage<GxmhCustomizeFormVo> page = new Page<>(queryDto.getPageNum(), queryDto.getPageSize());
        SysUserDto sysUserDto = gxmhSysMapper.queryUserInfo(loginId);
        if(sysUserDto == null) {
            throw new BusinessException("用户不存在");
        }
        if(!GxmhConstant.ADMIN_USER_NAME.equals(sysUserDto.getUsername())) {
            queryDto.setProvince(sysUserDto.getProvince());
            queryDto.setCity(sysUserDto.getCity());
            queryDto.setCounty(sysUserDto.getRegion());
            queryDto.setStreet(sysUserDto.getStreet());
        }
        List<GxmhCustomizeFormVo> list = this.baseMapper.queryCustomizeFormList(page, queryDto);
        PageResult<GxmhCustomizeFormVo> pageResult = new PageResult<>(list, new PageInfo(queryDto.getPageNum(), queryDto.getPageSize()), page.getTotal());
        return pageResult;
    }

    /**
     * 添加自定义表单
     * @param dto
     * @param loginId
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addCustomizeForm(GxmhFormDto dto, String loginId) {
        if(StrUtil.isBlank(dto.getFormTitle()) || CollectionUtil.isEmpty(dto.getFormFieldList())) {
            throw new BusinessException("表单标题和字段不能为空");
        }
        if(StrUtil.isBlank(dto.getTypeOneId()) || StrUtil.isBlank(dto.getTypeOneName()) || StrUtil.isBlank(dto.getTypeTwoId()) || StrUtil.isBlank(dto.getTypeTwoName())) {
            throw new BusinessException("表单类型不能为空");
        }
        if("default".equals(dto.getTypeOneId()) || "default-child".equals(dto.getTypeTwoId())) {
            throw new BusinessException("请创建或选择其他表单类型，不支持在系统默认表单类型下创建自定义表单");
        }
        // 1. 保存表单信息
        String formId = this.saveCustomizeForm(dto, loginId);
        // 2. 保存表单字段信息
        this.saveFormFieldList(dto, formId);
    }

    /**
     * 修改自定义表单
     * @param dto
     * @param loginId
     */
    @Override
    public void updateCustomizeForm(GxmhFormDto dto, String loginId) {
        if(StrUtil.isBlank(dto.getBaseId()) || StrUtil.isBlank(dto.getFormTitle()) || CollectionUtil.isEmpty(dto.getFormFieldList())) {
            throw new BusinessException("表单标题和字段不能为空");
        }
        if(GxmhConstant.DEFAULT_FORM_ID.equals(dto.getBaseId())) {
            throw new BusinessException("默认表单不能修改");
        }
        // 0. 如果当前表单已经挂接政策，且被挂接的政策已经存在申报数据，则不允许修改
        this.checkFormData(dto.getBaseId());
        // 1. 更新表单信息
        GxmhCustomizeForm customizeForm = new GxmhCustomizeForm();
        customizeForm.setBaseId(dto.getBaseId());
        customizeForm.setTypeOneId(dto.getTypeOneId());
        customizeForm.setTypeTwoId(dto.getTypeTwoId());
        customizeForm.setTypeOneName(dto.getTypeOneName());
        customizeForm.setTypeTwoName(dto.getTypeTwoName());
        customizeForm.setFormTitle(dto.getFormTitle());
        customizeForm.setBaseUpdateBy(loginId);
        customizeForm.setBaseUpdateTime(new Date());
        customizeForm.setTypeOneId(dto.getTypeOneId());
        customizeForm.setTypeTwoId(dto.getTypeTwoId());
        customizeForm.setTypeOneName(dto.getTypeOneName());
        customizeForm.setTypeTwoName(dto.getTypeTwoName());
        this.updateById(customizeForm);
        // 2. 删除表单字段信息
        LambdaQueryWrapper<GxmhCustomizeFormMeta> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GxmhCustomizeFormMeta::getFormId, dto.getBaseId());
        gxmhCustomizeFormMetaService.remove(queryWrapper);
        // 3. 重新添加表单字段信息
        this.saveFormFieldList(dto, dto.getBaseId());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteCustomizeForm(String formId) {
        if(GxmhConstant.DEFAULT_FORM_ID.equals(formId)) {
            throw new BusinessException("默认表单不能删除");
        }
        if(StrUtil.isBlank(formId)) {
            throw new BusinessException("表单标识不能为空");
        }
        // 0. 如果当前表单已经挂接政策，且被挂接的政策已经存在申报数据，则不允许修改
        this.checkFormData(formId);
        // 1. 删除表单字段信息
        LambdaQueryWrapper<GxmhCustomizeFormMeta> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GxmhCustomizeFormMeta::getFormId, formId);
        gxmhCustomizeFormMetaService.remove(queryWrapper);
        // 2. 删除表单
        this.removeById(formId);
    }

    // 检查表单是否已存在业务数据
    private void checkFormData(String formId) {
        List<String> policyIdList = this.baseMapper.queryPolicyIdListByFormId(formId);
        if(CollectionUtil.isNotEmpty(policyIdList)) {
            Integer declareCount = this.baseMapper.queryPolicyDeclareCount(policyIdList);
            if(declareCount > 0) {
                throw new BusinessException("当前表单已经挂接政策，且被挂接的政策已经存在申报数据，不允许修改");
            }
        }
    }

    @Override
    public GxmhFormDto getFromDetail(String formId) {
        GxmhFormDto dto = new GxmhFormDto();
        // 查询表单信息
        GxmhCustomizeForm customizeForm = this.baseMapper.selectById(formId);
        if(customizeForm == null) {
            throw new BusinessException("表单数据不存在");
        }
        // 查询表单字段信息
        LambdaQueryWrapper<GxmhCustomizeFormMeta> query = new LambdaQueryWrapper<>();
        query.eq(GxmhCustomizeFormMeta::getFormId, formId).orderByAsc(GxmhCustomizeFormMeta::getSort);
        List<GxmhCustomizeFormMeta> metaList = gxmhCustomizeFormMetaMapper.selectList(query);

        List<GxmhFormItemMetaDto> formFieldList = new ArrayList<>();
        for(GxmhCustomizeFormMeta meta : metaList){
            GxmhFormItemMetaDto item = new GxmhFormItemMetaDto();
            item.setFieldName(meta.getFieldName());
            item.setFieldType(meta.getFieldType());
            item.setNotEmpty(meta.getNotEmpty());
            item.setSort(meta.getSort());
            item.setFiledValue("");
            if(StrUtil.isNotEmpty(meta.getItemList())) {
                List<GxmhFormFieldItemDto> itemList = JSON.parseArray(meta.getItemList(), GxmhFormFieldItemDto.class);
                for(GxmhFormFieldItemDto itemDto : itemList) {
                    itemDto.setChecked(0);
                }
                item.setItemList(itemList);
            }

            formFieldList.add(item);
        }
        // 组装数据
        dto.setBaseId(formId);
        dto.setFormTitle(customizeForm.getFormTitle());
        dto.setFormFieldList(formFieldList);
        dto.setTypeOneId(customizeForm.getTypeOneId());
        dto.setTypeOneName(customizeForm.getTypeOneName());
        dto.setTypeTwoId(customizeForm.getTypeTwoId());
        dto.setTypeTwoName(customizeForm.getTypeTwoName());
        return dto;
    }

    // 保存表单信息
    private String saveCustomizeForm(GxmhFormDto dto, String loginId) {
        SysUserDto sysUserDto = gxmhSysMapper.queryUserInfo(loginId);
        if(sysUserDto == null) {
            throw new BusinessException("用户不存在");
        }
        String baseId = IdUtil.simpleUUID();
        GxmhCustomizeForm customizeForm = new GxmhCustomizeForm();
        customizeForm.setBaseId(baseId);
        customizeForm.setFormTitle(dto.getFormTitle());
        customizeForm.setTypeOneId(dto.getTypeOneId());
        customizeForm.setTypeOneName(dto.getTypeOneName());
        customizeForm.setTypeTwoId(dto.getTypeTwoId());
        customizeForm.setTypeTwoName(dto.getTypeTwoName());
        customizeForm.setBaseCreateBy(loginId);
        customizeForm.setBaseUpdateBy(loginId);
        customizeForm.setBaseCreateTime(new Date());
        customizeForm.setBaseUpdateTime(new Date());
        // 查询表单德类型获，类型的区域
        GxmhCustomizeFormType gxmhCustomizeFormType = gxmhCustomizeFormTypeMapper.selectById(dto.getTypeOneId());
        customizeForm.setProvince(gxmhCustomizeFormType.getProvince());
        customizeForm.setCity(gxmhCustomizeFormType.getCity());
        customizeForm.setCounty(gxmhCustomizeFormType.getCounty());
        customizeForm.setStreet(gxmhCustomizeFormType.getStreet());
        this.save(customizeForm);
        return baseId;
    }

    // 保存表单字段
    private void saveFormFieldList(GxmhFormDto dto, String formId) {
        List<GxmhFormItemMetaDto> formFieldList = dto.getFormFieldList();
        List<GxmhCustomizeFormMeta> metaList = new ArrayList<>();
        int sort = 1;
        for(GxmhFormItemMetaDto item : formFieldList){
            GxmhCustomizeFormMeta meta = new GxmhCustomizeFormMeta();
            meta.setBaseId(IdUtil.simpleUUID());
            meta.setFormId(formId);
            meta.setFieldName(item.getFieldName());
            meta.setFieldType(item.getFieldType());
            meta.setNotEmpty(item.getNotEmpty());
            meta.setSort(sort);
            sort++;
            if(CollectionUtil.isNotEmpty(item.getItemList())) {
                meta.setItemList(JSONObject.toJSONString(item.getItemList()));
            }
            metaList.add(meta);
        }
        if(!metaList.isEmpty()) {
            gxmhCustomizeFormMetaService.saveBatch(metaList);
        }
    }

}
